package cn.pm.datasource.sharding.converter;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.parser.JSONScanner;
import lombok.extern.slf4j.Slf4j;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.core.convert.converter.Converter;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * Create by spf on 2019/03/13
 * 日期转换器
\\
 * json类型的日期转换参看{@link DateConverter4Json}
 */
@Slf4j
public class DateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        if (StringUtils.isBlank(source)) {
            return null;
        }
        try {

            // 参考fastJson反序列化，能够显著提高反序列化性能
            JSONScanner dateLexer = new JSONScanner(source);
            try {
                if (dateLexer.scanISO8601DateIfMatch(false)) {
                    Calendar calendar = dateLexer.getCalendar();
                    return calendar.getTime();
                }
            } finally {
                dateLexer.close();
            }

            if (source.startsWith("/Date(") && source.endsWith(")/")) {
                String dotnetDateStr = source.substring(6, source.length() - 2);
                source = dotnetDateStr;
            }

            if ("0000-00-00".equals(source)
                    || "0000-00-00T00:00:00".equalsIgnoreCase(source)
                    || "0001-01-01T00:00:00+08:00".equalsIgnoreCase(source)) {
                return null;
            }

            int index = source.lastIndexOf('|');
            if (index > 20) {
                String tzStr = source.substring(index + 1);
                TimeZone timeZone = TimeZone.getTimeZone(tzStr);
                if (!"GMT".equals(timeZone.getID())) {
                    String subStr = source.substring(0, index);
                    dateLexer = new JSONScanner(subStr);
                    try {
                        if (dateLexer.scanISO8601DateIfMatch(false)) {
                            Calendar calendar = dateLexer.getCalendar();
                            calendar.setTimeZone(timeZone);
                            return calendar.getTime();
                        }
                    } finally {
                        dateLexer.close();
                    }
                }
            }

            // 时间戳处理
            if (source.matches("^\\d{13}$")) {
                return new Date(Long.parseLong(source));
            } else if (source.matches("^[1-9]\\d{3}-(0?[1-9]|1[0-2])$")) {
                return DateUtil.parse(source, "yyyy-MM");
            } else if (source.matches("^[1-9]\\d{3}$")) {
                return DateUtil.parse(source, "yyyy");
            } else if (source.matches("^(20|21|22|23|[0-1]?\\d):[0-5]?\\d")) {
                return DateUtil.parse(source, "HH:mm");
            }
        } catch (Exception e) {
            // skip
        }
        log.error("日期类型转换失败！ Params:{}", source);
        return null;
    }
}

